package csc.fresher.service.impl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import csc.fresher.constant.ProjectBankingConstant;
import csc.fresher.dao.AccountOverallDao;
import csc.fresher.dao.CustomerAccountDao;
import csc.fresher.dao.CustomerDao;
import csc.fresher.dao.PeriodTypeDao;
import csc.fresher.dao.SavingAccountDao;
import csc.fresher.dao.SavingAccountTransactionDao;
import csc.fresher.dao.SystemUserDao;
import csc.fresher.dao.impl.SavingAccountDaoImpl;
import csc.fresher.dao.impl.SavingAccountHasInterestRateDaoImpl;
import csc.fresher.dao.impl.SavingInterestRateDaoImpl;
import csc.fresher.entity.AccountHasInterestRate;
import csc.fresher.entity.AccountHasInterestRateState;
import csc.fresher.entity.AccountTransactionState;
import csc.fresher.entity.Customer;
import csc.fresher.entity.CustomerAccount;
import csc.fresher.entity.CustomerAccountOverall;
import csc.fresher.entity.InterestRate;
import csc.fresher.entity.PeriodType;
import csc.fresher.entity.SavingAccount;
import csc.fresher.entity.SavingAccountHasInterestRate;
import csc.fresher.factory.CustomerAccountDaoFactory;
import csc.fresher.service.SavingAccountService;

@Service
public class SavingAccountServiceImpl implements SavingAccountService {

	/*
	 * @Autowired SavingAccountDao savingAccountDao;
	 */
	@Autowired
	AccountOverallDao accountOverallDao;

	@Autowired
	CustomerAccountDaoFactory customerDaoFactory;
	@Autowired
	SavingAccountHasInterestRateDaoImpl savingAccountHasInterestRateDaoImpl;
	@Autowired
	CustomerDao customerDao;
	@Autowired
	SavingAccountTransactionDao savingAccountTransactionDao;
	@Autowired
	SystemUserDao systemUserDao;
	@Autowired
	SavingInterestRateDaoImpl savingInterestRateDaoImpl;
	@Autowired
	PeriodTypeDao periodTypeDao;
	
	@Autowired
	SavingAccountDao savingAccountDao;

	CustomerAccountDao customerAccountDao = null;

	@PostConstruct
	public void init() {
		customerAccountDao = customerDaoFactory
				.getType(ProjectBankingConstant.SAVING_ACCOUNT_TYPE);
	}

	@Override
	public List<CustomerAccount> getListCustomerAccountByIDCardNumber(
			long idCardNumber) {
		List<CustomerAccount> customerAccounts = new ArrayList<CustomerAccount>();

		if (customerAccountDao != null) {
			customerAccounts = customerAccountDao
					.getListCutomerAccountsbyCardNumberID(idCardNumber);
		}
		return customerAccounts;
	}

	@Override
	public CustomerAccount getCustomerAccountByID(long idCardNumber) {
		CustomerAccount customerAccount = null;
		if (customerAccountDao != null) {
			customerAccount = customerAccountDao
					.getCustomerAccountByID(idCardNumber);
		}
		return customerAccount;
	}

	@Override
	public double getCurrentAccountBalance(CustomerAccount customerAccount) {
		/*
		 * long accountID = customerAccount.getAccountNumber();
		 * SavingAccountHasInterestRate savingAccountHasInterestRate =
		 * savingAccountHasInterestRateDaoImpl
		 * .getInterestRateByAccountNumberID(accountID);
		 * if(savingAccountHasInterestRate != null &&
		 * savingAccountHasInterestRate.getAccountNumber() != 0){ double balance
		 * = customerAccount.getAccountBalance();
		 * 
		 * SavingTransaction savingTransaction =
		 * savingAccountTransactionDao.getLastSavingTransactionIsApproved
		 * (accountID);
		 * 
		 * 
		 * if(savingAccountHasInterestRate.getToDate().getTime() <=
		 * savingTransaction.getBeginTime().getTime() &&
		 * savingTransaction.getSavingTransactionType
		 * ().equals(SavingTransactionType.WITHDRAW)){ return balance; }
		 * System.out.println("balance " + balance + " rate " +
		 * savingAccountHasInterestRate.getInterestRate().getRate());
		 * 
		 * return balance + balance *
		 * savingAccountHasInterestRate.getInterestRate().getRate() / 100;
		 * 
		 * }
		 */

		return customerAccount.getAccountBalance();
	}

	@Override
	public CustomerAccount getCustomerAccountByAccNumber(long accNumber) {
		// TODO Auto-generated method stub
		CustomerAccount customerAccount = null;

		if (customerAccountDao != null) {
			customerAccount = customerAccountDao
					.getCustomerAccountByID(accNumber);
		}
		return customerAccount;
	}

	@Override
	public Customer getCustomerByCustomerID(long customerID) {
		Customer customer = null;
		if (customerDao != null) {
			customer = customerDao.getCustomerByID(customerID);
		}
		return customer;
	}

	@Override
	public List<CustomerAccountOverall> getAccountByIDCardNumber(
			long idCardNumber, String accountType) {
		return accountOverallDao.getAccountByIDCardNumber(idCardNumber,
				accountType);
	}

	@Override
	public List<CustomerAccountOverall> getAccountByFirstName(String firstName,
			String accountType) {
		return accountOverallDao.getAccountByFirstName(firstName, accountType);
	}

	@Override
	public List<CustomerAccountOverall> getAccountByAccountNumber(
			long accountNumber, String accountType) {
		return accountOverallDao.getAccountByAccountNumber(accountNumber,
				accountType);
	}

	@Override
	public List<CustomerAccountOverall> getAccountByEmail(String email,
			String accountType) {
		return accountOverallDao.getAccountByEmail(email, accountType);
	}

	@Override
	public List<CustomerAccount> getAllSavingAccounts() {
		List<CustomerAccount> customerAccounts = new ArrayList<CustomerAccount>();

		if (savingAccountDao != null) {
			customerAccounts = savingAccountDao.getAllSavingAccounts();
		}
		return customerAccounts;
	}

	@Override
	public boolean checkInterestRateExpiredDate(CustomerAccount customerAccount) {
		if (customerAccount.getAccountTransactionState().getState()
				.equals(AccountTransactionState.HOLD.getState())) {
			
			long accountNumber = customerAccount
					.getAccountNumber();
			AccountHasInterestRate accountHasInterestRate = savingAccountHasInterestRateDaoImpl
					.getInterestRateByAccountNumberID(accountNumber);
			AccountHasInterestRate newestAccountHasInterestRate = savingAccountHasInterestRateDaoImpl.getNewestInterestRateByAccountNumberID(accountNumber);
			
			
			if (accountHasInterestRate != null
					&& accountHasInterestRate.getToDate().getTime() <= System
							.currentTimeMillis() &&  !newestAccountHasInterestRate.getState().getState().equals(AccountHasInterestRateState.PENDING.getState())) {
				double balance = customerAccount.getAccountBalance();
				
				long time = accountHasInterestRate.getToDate().getTime() - accountHasInterestRate.getFromDate().getTime();
				int numberOfDays = (int) (time / (86400000));//1000*60*60*24
				
				//PeriodType periodType = periodTypeDao.getPeriodTypeByID(accountHasInterestRate.getInterestRate().getPeriodTypeID());
				
				
				balance = balance + balance
						* accountHasInterestRate.getInterestRate().getRate()*numberOfDays
						/ 36000; // 12 * 100 * 30
				SavingAccountDaoImpl savingAccountDaoImpl = (SavingAccountDaoImpl) customerAccountDao;
				SavingAccount savingAccount = (SavingAccount) customerAccount;
				savingAccount.setAccountBalance(balance);
				savingAccount
						.setAccountTransactionState(AccountTransactionState.ACTIVE);
				savingAccountDaoImpl.update(savingAccount);
				return true;
			}
		}

		return false;
	}

	@Override
	public boolean calculateProfitBeforeExpiredDate(
			CustomerAccount customerAccount) {

		SavingAccount savingAccount = (SavingAccount) customerAccount;
		if (savingAccount.getAccountTransactionState().getState()
				.equals(AccountTransactionState.HOLD.getState())) {
			long accountNumber = savingAccount.getAccountNumber();
			AccountHasInterestRate accountHasInterestRate = savingAccountHasInterestRateDaoImpl
					.getInterestRateByAccountNumberID(accountNumber);

			Timestamp fromDate = accountHasInterestRate.getFromDate();
			Timestamp toDate = accountHasInterestRate.getToDate();
			if (toDate.getTime() > System.currentTimeMillis()) {
				double balance = customerAccount.getAccountBalance();

				Calendar cal = Calendar.getInstance();       // get calendar instance
				cal.setTimeInMillis(System.currentTimeMillis());     // set cal to date
				cal.set(Calendar.HOUR_OF_DAY, 0);            // set hour to midnight
				cal.set(Calendar.MINUTE, 0);                 // set minute in hour
				cal.set(Calendar.SECOND, 0);                 // set second in minute
				cal.set(Calendar.MILLISECOND, 0);            // set millis in second
				Timestamp currentDate = new Timestamp(cal.getTimeInMillis());
				
				long time = currentDate.getTime() - fromDate.getTime();
				long days = time / 86400000;// 24 * 60 * 60 * 1000

				InterestRate interestRate = savingInterestRateDaoImpl
						.getInterestRateByType(savingAccount.getCurrencyID(),
								ProjectBankingConstant.NONE_DURATION);

				accountHasInterestRate
						.setState(AccountHasInterestRateState.CANCEL);

				AccountHasInterestRate accountHasInterestRate2 = new SavingAccountHasInterestRate(
						accountNumber, interestRate.getInterestRateID(),
						fromDate, new Timestamp(System.currentTimeMillis()),
						balance, AccountHasInterestRateState.ACCEPTED);
				balance = balance + balance * interestRate.getRate() * days
						/ 36000; // 12 * 100 * 30

				SavingAccountDaoImpl savingAccountDaoImpl = (SavingAccountDaoImpl) customerAccountDao;
				savingAccount.setAccountBalance(balance);
				savingAccount
						.setAccountTransactionState(AccountTransactionState.ACTIVE);
				return savingAccountDaoImpl.changeRateBeforeExpiredDate(
						savingAccount, accountHasInterestRate,
						accountHasInterestRate2);
			}
		}
		return false;
	}

	@Override
	public List<CustomerAccount> getSavingAccountsIsRepeatable() {
		List<CustomerAccount> customerAccounts = null;
		Timestamp today = new Timestamp(System.currentTimeMillis());
		if (customerAccountDao != null) {
			customerAccounts = savingAccountDao.getAllIsRepeatableSavingAccountByDate(today);
		}
		return customerAccounts;
	}
	
	@Override
	public boolean updateSavingAccount(SavingAccount savingAccount) {
		if(savingAccountDao != null){
			if(savingAccountDao.update(savingAccount))
				return true;
		}
		return false;
	}
	
	@Override
	public boolean updatePeriod(SavingAccount savingAccount) {
		if(savingAccountDao != null){
			if(savingAccountDao.repeatPeriod(savingAccount))
				return true;
		}
		return false;
	}
}
